﻿using System.Linq;
using System.Threading.Tasks;
using housingsafety.server.Caching.Core;
using housingsafety.server.Entities.DataModels;
using housingsafety.server.Helpers;
using housingsafety.server.Models;
using housingsafety.server.Repository;
using Microsoft.AspNetCore.Authorization;

namespace housingsafety.server.Security
{
    /// <summary>
    /// 要求管理员处理器
    /// </summary>
    public class AdminOnlyHandler : AuthorizationHandler<AdminOnlyRequirement>
    {
        private readonly ICache _cache;
        private readonly IRepository<ZmUser> _userRepository;

        public AdminOnlyHandler(ICacheProvider cacheProvider, IRepository<ZmUser> userRepository)
        {
            _cache = cacheProvider.CreateCache();
            _userRepository = userRepository;
        }
        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="context"></param>
        /// <param name="requirement"></param>
        /// <returns></returns>
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
            AdminOnlyRequirement requirement)
        {
            var currentUser = context.User.CurrentUser();
            if (!string.IsNullOrEmpty(currentUser))
            {
                UserRoleSet roleSet = _cache
                    .GetOrDb(ConstRedisKeys.UserRoles(currentUser), (_) =>
                    {
                        var user = _userRepository.Query(u => u.Number == currentUser).FirstOrDefault();
                        if (null != user)
                        {
                            UserRoleSet urs = new UserRoleSet(user.Number, user.SysAdmin == 1);
                            _cache.Set(_, urs);
                            return urs;
                        }

                        return null;
                    });
                if (null != roleSet && roleSet.SysAdmin)
                {
                    context.Succeed(requirement);
                }
            }

            //TODO: Use the following if targeting a version of
            //.NET Framework older than 4.6:
            //      return Task.FromResult(0);
            return Task.CompletedTask;
        }
    }
}